from django.http import JsonResponse
import json
from ..models import User, WfDesign, StuTeaRelation, WfDesignStep
from django.core.paginator import Paginator
from django.db.models import Q, F
from django.db import transaction


def wfdesign_handle(request):
    if request.method == 'GET':
        request.params = request.GET
    else:
        request.params = json.loads(request.body)
    action = request.params.get('action')

    if not request.user.is_authenticated:
        return JsonResponse({'ret': 1, 'msg': '未登录'}, json_dumps_params={'ensure_ascii': False})
    if action in action_handler_dict:
        return action_handler_dict[action](request)
    return JsonResponse({'ret': 1, 'msg': 'action参数错误'})

def listbypage(request):
    try:
        user = request.user
        if user.usertype == 2000:
            qs = WfDesign.objects.filter(creator=user).values(
                'id', 'creator', 'creator__realname', 
                'title', 'currentstate', 'createdate')
        elif user.usertype == 3000:
            creators = StuTeaRelation.objects.filter(teacher=user).values_list('student', flat=True)
            qs = WfDesign.objects.filter(creator__in=creators).exclude(currentstate__contains='废弃').values(
                'id', 'creator', 'creator__realname', 'title', 'currentstate', 'createdate')
        pagesize = request.params.get('pagesize')
        pagenum = request.params.get('pagenum')
        keywords = request.params.get('keywords')
        if keywords:
            keywords_list = keywords.split()
            query = Q()
            for k in keywords_list:
                query &= Q(title__contains=k)
            qs = qs.filter(query)
        pgnt = Paginator(qs, pagesize)
        page = pgnt.get_page(pagenum)
        items = list(page)
        return JsonResponse(
            {
                'ret': 0, 
                'items': items, 
                'total': pgnt.count,
                'keywords': keywords
            }, json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def getone_create(request):
    try:
        user = request.user
        wfid = int(request.params['wf_id'])
        if wfid != -1:
            return getone_one(request)
        if user.usertype != 2000:
            return JsonResponse({'ret': 1, 'msg': '仅学生可以创建'})
        create_topic = {
            "name": "创建主题",
            "submitdata": [
                {
                "name": "毕业设计标题",
                "type": "text",
                "check_string_len": [1, 50]
                },
                {
                "name": "主题描述",
                "type": "richtext",
                "check_string_len": [10, 10000]
                }
            ],
            "whocan": user.id,
            "next": "主题已创建",
            "key": "create_topic"
        }
        whaticando = [create_topic]
        return JsonResponse({
            "ret": 0,
            "rec": {
                "id": -1,
                "creatorname": "",
                "title": "",
                "currentstate": "",
                "createdate": ""
            },
            "whaticando": whaticando
        })
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def getone_one(request):
    try:
        user = request.user
        wfid = int(request.params['wf_id'])
        wf = WfDesign.objects.filter(id=wfid).annotate(creatorname=F('creator__realname')).values(
            'id', 'creator', 'creatorname', 'title', 'currentstate', 'createdate')[0]
        steps = WfDesignStep.objects.filter(wf=wfid).values(
            'id', 'operator__realname', 'actiondate', 'actionname', 'nextstate')
        wf['steps'] = list(steps)
        creator = wf['creator']
        try:
            teacher = StuTeaRelation.objects.get(student_id = wf['creator']).teacher_id
        except:
            teacher = None
        reject_topic = {
            "name": "驳回主题",
            "submitdata": [
                {
                "name": "驳回原因",
                "type": "richtext",
                "check_string_len": [0, 10000]
                }
            ],
            "whocan": teacher,
            "next": "主题被驳回",
            "key": "reject_topic"
        }
        approve_topic = {
            "name": "批准主题",
            "submitdata": [
                {
                "name": "备注",
                "type": "textarea",
                "check_string_len": [0, 10000]
                }
            ],
            "whocan": teacher,
            "next": "主题已通过",
            "key": "approve_topic"
        }
        abandon_topic = {
            "name": "废弃流程",
            "submitdata": [
                {
                "name": "备注",
                "type": "textarea",
                "check_string_len": [0, 10000]
                }
            ],
            "whocan": creator,
            "next": "结束",
            "key": "abandon_topic"
        }
        modify_topic = {
            "name": "修改主题",
            "submitdata": [
                {
                "name": "毕业设计标题",
                "type": "text",
                "check_string_len": [1, 50]
                },
                {
                "name": "主题描述",
                "type": "richtext",
                "check_string_len": [10, 10000]
                }
            ],
            "whocan": creator,
            "next": "主题已修改",
            "key": "modify_topic"
        }
        submit_design = {
            "name": "提交毕业设计",
            "submitdata": [
                {
                "name": "毕业设计内容",
                "type": "richtext",
                "check_string_len": [20, 50000]
                }
            ],
            "whocan": creator,
            "next": "学生已提交毕业设计",
            "key": "submit_design"
        }
        mark_design = {
            "name": "评分",
            "submitdata": [
                {
                "name": "分数",
                "type": "int",
                "check_int_range": [0, 100]
                },
                {
                "name": "备注",
                "type": "textarea",
                "check_string_len": [0, 10000]
                }
            ],
            "whocan": teacher,
            "next": "结束",
            "key": "mark_design"
        }
        reject_design = {
            "name": "驳回毕业设计",
            "submitdata": [
                {
                "name": "驳回原因",
                "type": "richtext",
                "check_string_len": [0, 10000]
                }
            ],
            "whocan": teacher,
            "next": "毕业设计被驳回",
            "key": "reject_design"
        }
        if wf['currentstate'] in ['主题已创建', '主题已修改']:
            if user.usertype == 3000:
                whaticando = [reject_topic, approve_topic]
            else:
                whaticando = [abandon_topic]
        elif wf['currentstate'] == '主题被驳回':
            if user.usertype == 3000:
                whaticando = []
            else:
                whaticando = [modify_topic, abandon_topic]
        elif wf['currentstate'] == '主题已通过':
            if user.usertype == 3000:
                whaticando = []
            else:
                whaticando = [submit_design, abandon_topic]
        elif wf['currentstate'] == '学生已提交毕业设计':
            if user.usertype == 3000:
                whaticando = [mark_design, reject_design]
            else:
                whaticando = [abandon_topic]
        elif wf['currentstate'] == '毕业设计被驳回':
            if user.usertype == 3000:
                whaticando = []
            else:
                whaticando = [submit_design, abandon_topic]
        elif ('废弃' in wf['currentstate']) or (wf['currentstate'] == '已评分'):
            whaticando = None
        return JsonResponse({
            'ret': 0,
            "rec": wf,
            "whaticando": whaticando
        })
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def stepaction(request):
    key = request.params['key']
    return stepaction_handler_dict[key](request)

def create_topic(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        if user.usertype != 2000:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            wf = WfDesign.objects.create(
                creator=user, title=submitdata[0]['value'], currentstate='主题已创建')
            WfDesignStep.objects.create(
                wf=wf, operator=user, 
                actionname='创建主题',
                nextstate='主题已创建',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf.id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def modify_topic(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        wf_id = request.params['wf_id']
        wf = WfDesign.objects.get(id=wf_id)
        if user != wf.creator:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            wf.title = submitdata[0]['value']
            wf.currentstate = '主题已修改'
            wf.save()
            WfDesignStep.objects.create(
                wf=wf, operator=user, 
                actionname='修改主题',
                nextstate='主题已修改',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf.id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def abandon_topic(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        wf_id = request.params['wf_id']
        wf = WfDesign.objects.get(id=wf_id)
        if ('废弃' in wf.currentstate) or (wf.currentstate == '已评分'):
            return JsonResponse({'ret': 1, 'msg': '不能进行此操作'})
        if user != wf.creator:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            wf.currentstate = '已废弃'
            wf.save()
            WfDesignStep.objects.create(
                wf=wf, operator=user, 
                actionname='废弃流程',
                nextstate='结束',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf.id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def approve_topic(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        wf_id = request.params['wf_id']
        wf = WfDesign.objects.get(id=wf_id)
        stutea = StuTeaRelation.objects.get(student=wf.creator)
        if wf.currentstate not in ['主题已创建', '主题已修改']:  # TODO hff
            return JsonResponse({'ret': 1, 'msg': '不能进行此操作'})
        if user != stutea.teacher:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            WfDesign.objects.filter(id=wf_id).update(
                currentstate='主题已通过')
            WfDesignStep.objects.create(
                wf_id=wf_id, operator=user, 
                actionname='批准主题',
                nextstate='主题已通过',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf_id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def reject_topic(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        wf_id = request.params['wf_id']
        wf = WfDesign.objects.get(id=wf_id)
        stutea = StuTeaRelation.objects.get(student=wf.creator)
        if wf.currentstate not in ['主题已创建', '主题已修改']:
            return JsonResponse({'ret': 1, 'msg': '不能进行此操作'})
        if user != stutea.teacher:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            WfDesign.objects.filter(id=wf_id).update(
                currentstate='主题被驳回')
            WfDesignStep.objects.create(
                wf_id=wf_id, operator=user, 
                actionname='驳回主题',
                nextstate='主题被驳回',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf_id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def submit_design(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        wf_id = request.params['wf_id']
        wf = WfDesign.objects.get(id=wf_id)
        if wf.currentstate not in ['主题已通过', '毕业设计被驳回']:
            return JsonResponse({'ret': 1, 'msg': '不能进行此操作'})
        if user != wf.creator:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            wf.currentstate = '学生已提交毕业设计'
            wf.save()
            WfDesignStep.objects.create(
                wf=wf, operator=user, 
                actionname='提交毕业设计',
                nextstate='学生已提交毕业设计',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf.id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def mark_design(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        wf_id = request.params['wf_id']
        wf = WfDesign.objects.get(id=wf_id)
        stutea = StuTeaRelation.objects.get(student=wf.creator)
        if wf.currentstate != '学生已提交毕业设计':
            return JsonResponse({'ret': 1, 'msg': '不能进行此操作'})
        if user != stutea.teacher:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            wf.currentstate = '已评分'
            wf.save()
            WfDesignStep.objects.create(
                wf_id=wf_id, operator=user, 
                actionname='评分',
                nextstate='结束',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf_id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def reject_design(request):
    try:
        user = request.user
        submitdata = request.params['submitdata']
        wf_id = request.params['wf_id']
        wf = WfDesign.objects.get(id=wf_id)
        stutea = StuTeaRelation.objects.get(student=wf.creator)
        if wf.currentstate != '学生已提交毕业设计':
            return JsonResponse({'ret': 1, 'msg': '不能进行此操作'})
        if user != stutea.teacher:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        with transaction.atomic():
            WfDesign.objects.filter(id=wf_id).update(
                currentstate='毕业设计被驳回')
            WfDesignStep.objects.create(
                wf_id=wf_id, operator=user, 
                actionname='驳回毕业设计',
                nextstate='毕业设计被驳回',
                submitdata=json.dumps(submitdata, ensure_ascii=False)
            )
            return JsonResponse({'ret': 0, 'wf_id': wf_id})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

def getstepactiondata(request):
    try:
        user = request.user
        step_id = request.params['step_id']
        step = WfDesignStep.objects.get(id=step_id)
        wf = step.wf
        try:
            teacher = wf.creator.stutearelation.teacher
        except:
            teacher = wf.creator
        if user not in [teacher, wf.creator]:
            return JsonResponse({'ret': 1, 'msg': '权限不足'})
        data = json.loads(step.submitdata)
        return JsonResponse({'ret': 0, 'data': data})
    except Exception as e:
        return JsonResponse({'ret': 1, 'msg': str(e)})

action_handler_dict = {
    'listbypage': listbypage,
    'getone': getone_create,
    'stepaction': stepaction,
    'getstepactiondata': getstepactiondata,
}

stepaction_handler_dict = {
    'create_topic': create_topic,
    'modify_topic': modify_topic,
    'abandon_topic': abandon_topic,
    'approve_topic': approve_topic,
    'reject_topic': reject_topic,
    'submit_design': submit_design,
    'mark_design': mark_design,
    'reject_design': reject_design,
}